# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.1069.1.110+1.1069.113.2 -> 1.1069.119.1
#	drivers/acpi/pci_root.c	1.4.1.1 -> 1.7    
#	            Makefile	1.190.1.60 -> 1.193.1.36
#	drivers/char/serial.c	1.33.1.4 -> 1.44   
#	arch/i386/kernel/mpparse.c	1.27.1.15 -> 1.30.1.9
#	arch/i386/kernel/io_apic.c	1.27.1.6 -> 1.29.1.4
#	drivers/acpi/system.c	1.13.1.2 -> 1.16   
#	arch/i386/kernel/pci-pc.c	1.30.1.4 -> 1.31.1.3
#	arch/i386/kernel/setup.c	1.68.1.10 -> 1.70.1.7
#	  drivers/acpi/bus.c	1.18.1.1 -> 1.20   
#	include/asm-i386/io_apic.h	1.10.1.3 -> 1.12.1.2
#	          fs/inode.c	1.36.1.6 -> 1.40.1.3
#
diff -Nru a/Makefile b/Makefile
--- a/Makefile	Thu Nov 20 16:16:44 2003
+++ b/Makefile	Thu Nov 20 16:16:44 2003
@@ -93,6 +93,7 @@
 
 CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -Wno-trigraphs -O2 \
 	  -fno-strict-aliasing -fno-common
+CFLAGS += -g
 ifndef CONFIG_FRAME_POINTER
 CFLAGS += -fomit-frame-pointer
 endif
@@ -306,8 +307,7 @@
 	$(CONFIG_SHELL) scripts/Configure -d arch/$(ARCH)/config.in
 
 xconfig: symlinks
-	$(MAKE) -C scripts kconfig.tk
-	wish -f scripts/kconfig.tk
+	@echo -e "***\n* Sorry, xconfig is broken; use \"make menuconfig\" instead.\n***"
 
 menuconfig: include/linux/version.h symlinks
 	$(MAKE) -C scripts/lxdialog all
diff -Nru a/drivers/acpi/bus.c b/drivers/acpi/bus.c
--- a/drivers/acpi/bus.c	Thu Nov 20 16:16:44 2003
+++ b/drivers/acpi/bus.c	Thu Nov 20 16:16:44 2003
@@ -1407,16 +1407,14 @@
 	switch (type) {
 	case ACPI_BUS_TYPE_DEVICE:
 		result = acpi_bus_get_status(device);
-		if (result)
-			goto end;
-		break;
+		if (!result)
+			break;
+		if (!device->status.present)
+			result = -ENOENT;
+		goto end;
 	default:
 		STRUCT_TO_INT(device->status) = 0x0F;
 		break;
-	}
-	if (!device->status.present) {
-		result = -ENOENT;
-		goto end;
 	}
 
 	/*
diff -Nru a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
--- a/drivers/acpi/pci_root.c	Thu Nov 20 16:16:44 2003
+++ b/drivers/acpi/pci_root.c	Thu Nov 20 16:16:44 2003
@@ -61,8 +61,6 @@
 	acpi_handle		handle;
 	struct acpi_pci_id	id;
 	struct pci_bus		*bus;
-	u64			mem_tra;
-	u64			io_tra;
 };
 
 static LIST_HEAD(acpi_pci_roots);
@@ -114,97 +112,6 @@
 	}
 }
 
-void
-acpi_pci_get_translations (
-	struct acpi_pci_id	*id,
-	u64			*mem_tra,
-	u64			*io_tra)
-{
-	struct list_head	*node = NULL;
-	struct acpi_pci_root	*entry;
-
-	/* TBD: Locking */
-	list_for_each(node, &acpi_pci_roots) {
-		entry = list_entry(node, struct acpi_pci_root, node);
-		if ((id->segment == entry->id.segment)
-			&& (id->bus == entry->id.bus)) {
-			*mem_tra = entry->mem_tra;
-			*io_tra = entry->io_tra;
-			return;
-		}
-	}
-
-	*mem_tra = 0;
-	*io_tra = 0;
-}
-
-
-static u64
-acpi_pci_root_bus_tra (
-       struct acpi_resource	*resource,
-       int			type)
-{
-	struct acpi_resource_address16 *address16;
-	struct acpi_resource_address32 *address32;
-	struct acpi_resource_address64 *address64;
-
-	while (1) {
-		switch (resource->id) {
-		case ACPI_RSTYPE_END_TAG:
-			return 0;
-
-		case ACPI_RSTYPE_ADDRESS16:
-			address16 = (struct acpi_resource_address16 *) &resource->data;
-			if (type == address16->resource_type) {
-				return address16->address_translation_offset;
-			}
-			break;
-
-		case ACPI_RSTYPE_ADDRESS32:
-			address32 = (struct acpi_resource_address32 *) &resource->data;
-			if (type == address32->resource_type) {
-				return address32->address_translation_offset;
-			}
-			break;
-
-		case ACPI_RSTYPE_ADDRESS64:
-			address64 = (struct acpi_resource_address64 *) &resource->data;
-			if (type == address64->resource_type) {
-				return address64->address_translation_offset;
-			}
-			break;
-		}
-		resource = ACPI_PTR_ADD (struct acpi_resource,
-				resource, resource->length);
-	}
-
-	return 0;
-}
-
-
-static int
-acpi_pci_evaluate_crs (
-	struct acpi_pci_root	*root)
-{
-	acpi_status		status;
-	struct acpi_buffer	buffer = {ACPI_ALLOCATE_BUFFER, NULL};
-
-	ACPI_FUNCTION_TRACE("acpi_pci_evaluate_crs");
-
-	status = acpi_get_current_resources (root->handle, &buffer);
-	if (ACPI_FAILURE(status))
-		return_VALUE(-ENODEV);
-
-	root->io_tra = acpi_pci_root_bus_tra ((struct acpi_resource *)
-			buffer.pointer, ACPI_IO_RANGE);
-	root->mem_tra = acpi_pci_root_bus_tra ((struct acpi_resource *)
-			buffer.pointer, ACPI_MEMORY_RANGE);
-
-	acpi_os_free(buffer.pointer);
-	return_VALUE(0);
-}
-
-
 static int
 acpi_pci_root_add (
 	struct acpi_device	*device)
@@ -245,8 +152,6 @@
 	switch (status) {
 	case AE_OK:
 		root->id.segment = (u16) value;
-		printk("_SEG exists! Unsupported. Abort.\n");
-		BUG();
 		break;
 	case AE_NOT_FOUND:
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
@@ -289,10 +194,8 @@
 	root->id.function = device->pnp.bus_address & 0xFFFF;
 
 	/*
-	 * Evaluate _CRS to get root bridge resources
 	 * TBD: Need PCI interface for enumeration/configuration of roots.
 	 */
- 	acpi_pci_evaluate_crs(root);
 
  	/* TBD: Locking */
  	list_add_tail(&root->node, &acpi_pci_roots);
@@ -308,7 +211,12 @@
 	 * PCI namespace does not get created until this call is made (and 
 	 * thus the root bridge's pci_dev does not exist).
 	 */
+#ifdef CONFIG_X86
 	root->bus = pcibios_scan_root(root->id.bus);
+#else
+	root->bus = pcibios_scan_root(root->handle,
+				      root->id.segment, root->id.bus);
+#endif
 	if (!root->bus) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 
 			"Bus %02x:%02x not present in PCI namespace\n", 
diff -Nru a/drivers/char/serial.c b/drivers/char/serial.c
--- a/drivers/char/serial.c	Thu Nov 20 16:16:44 2003
+++ b/drivers/char/serial.c	Thu Nov 20 16:16:44 2003
@@ -92,9 +92,8 @@
  * 		ever possible.
  *
  * CONFIG_SERIAL_ACPI
- *		Enable support for serial console port and serial 
- *		debug port as defined by the SPCR and DBGP tables in 
- *		ACPI 2.0.
+ *		Enable support for serial ports found in the ACPI
+ *		namespace.
  */
 
 #include <linux/config.h>
@@ -222,6 +221,10 @@
 #ifdef CONFIG_MAGIC_SYSRQ
 #include <linux/sysrq.h>
 #endif
+#ifdef ENABLE_SERIAL_ACPI
+#include <linux/acpi.h>
+#include <acpi/acpi_bus.h>
+#endif
 
 /*
  * All of the compatibilty code so we can compile serial.c against
@@ -257,6 +260,10 @@
 
 static struct timer_list serial_timer;
 
+#define HP_DIVA_CHECKTIME (1*HZ)
+static struct timer_list hp_diva_timer;
+static int hp_diva_count = 0;
+
 /* serial subtype definitions */
 #ifndef SERIAL_TYPE_NORMAL
 #define SERIAL_TYPE_NORMAL	1
@@ -793,6 +800,41 @@
 }
 
 #ifdef CONFIG_SERIAL_SHARE_IRQ
+static inline int is_hp_diva_info(struct async_struct *info) 
+{
+    struct pci_dev *dev = info->state->dev;
+    return (dev && dev->vendor == PCI_VENDOR_ID_HP &&
+		dev->device == PCI_DEVICE_ID_HP_SAS);
+}
+
+static inline int is_hp_diva_irq(int irq)
+{
+    struct async_struct *info = IRQ_ports[irq];
+    return (info && is_hp_diva_info(info));
+}
+
+/*
+ * It is possible to "use up" transmit empty interrupts in some
+ * cases with HP Diva cards.  Figure out if there _should_ be a
+ * transmit interrupt and if so, return a suitable iir value so
+ * that we can recover when called from rs_timer().
+ */
+static inline int hp_diva_iir(int irq, struct async_struct *info)
+{
+	int iir = serial_in(info, UART_IIR);
+
+	if (is_hp_diva_info(info) &&
+		(iir & UART_IIR_NO_INT) != 0 &&
+		(info->IER & UART_IER_THRI) != 0 &&
+		(info->xmit.head != info->xmit.tail || info->x_char) &&
+		(serial_in(info, UART_LSR) & UART_LSR_THRE) != 0) {
+		    iir &= ~(UART_IIR_ID | UART_IIR_NO_INT);
+		    iir |= UART_IIR_THRI;
+	}
+
+	return iir;
+}
+
 /*
  * This is the serial driver's generic interrupt routine
  */
@@ -823,7 +865,7 @@
 
 	do {
 		if (!info->tty ||
-		    ((iir=serial_in(info, UART_IIR)) & UART_IIR_NO_INT)) {
+		    ((iir=hp_diva_iir(irq, info)) & UART_IIR_NO_INT)) {
 			if (!end_mark)
 				end_mark = info;
 			goto next;
@@ -1097,9 +1139,11 @@
 #ifdef CONFIG_SERIAL_SHARE_IRQ
 			if (info->next_port) {
 				do {
-					serial_out(info, UART_IER, 0);
-					info->IER |= UART_IER_THRI;
-					serial_out(info, UART_IER, info->IER);
+					if (!is_hp_diva_info(info)) {
+						serial_out(info, UART_IER, 0);
+						info->IER |= UART_IER_THRI;
+						serial_out(info, UART_IER, info->IER);
+					}
 					info = info->next_port;
 				} while (info);
 #ifdef CONFIG_SERIAL_MULTIPORT
@@ -1131,6 +1175,35 @@
 }
 
 /*
+ * This subroutine is called when the hp_diva_timer goes off.  In
+ * certain cases (multiple gettys in particular) Diva seems to issue
+ * only a single transmit empty interrupt instead of one each time
+ * THRI is enabled, causing interrupts to be "used up".  This serves
+ * to poll the Diva UARTS more frequently than rs_timer() does.
+ */
+static void hp_diva_check(unsigned long dummy)
+{
+#ifdef CONFIG_SERIAL_SHARE_IRQ
+	static unsigned long last_strobe;
+	unsigned long flags;
+	int i;
+
+	if (time_after_eq(jiffies, last_strobe + HP_DIVA_CHECKTIME)) {
+		for (i = 0; i < NR_IRQS; i++) {
+			if (is_hp_diva_irq(i)) {
+			    save_flags(flags); cli();
+			    rs_interrupt(i, NULL, NULL);
+			    restore_flags(flags);
+			}
+		}
+	}
+	last_strobe = jiffies;
+	mod_timer(&hp_diva_timer, jiffies + HP_DIVA_CHECKTIME);
+#endif
+}
+
+
+/*
  * ---------------------------------------------------------------
  * Low level utility subroutines for the serial driver:  routines to
  * figure out the appropriate timeout for an interrupt chain, routines
@@ -4286,6 +4359,12 @@
 		break;
 	}
 
+	if (hp_diva_count++ == 0) {
+		init_timer(&hp_diva_timer);
+		hp_diva_timer.function = hp_diva_check;
+		mod_timer(&hp_diva_timer, jiffies + HP_DIVA_CHECKTIME);
+	}
+
 	return 0;
 }
 
@@ -4589,6 +4668,129 @@
 	}
 }
 
+#ifdef ENABLE_SERIAL_ACPI
+static acpi_status acpi_serial_address(struct serial_struct *req,
+				       struct acpi_resource_address64 *addr)
+{
+	unsigned long size;
+
+	size = addr->max_address_range - addr->min_address_range + 1;
+	req->iomem_base = ioremap(addr->min_address_range, size);
+	if (!req->iomem_base) {
+		printk("%s: couldn't ioremap 0x%lx-0x%lx\n", __FUNCTION__,
+			addr->min_address_range, addr->max_address_range);
+		return AE_ERROR;
+	}
+	req->io_type = SERIAL_IO_MEM;
+	return AE_OK;
+}
+
+static acpi_status acpi_serial_ext_irq(struct serial_struct *req,
+				       struct acpi_resource_ext_irq *ext_irq)
+{
+	if (ext_irq->number_of_interrupts > 0) {
+#ifdef CONFIG_IA64
+		req->irq = acpi_register_irq(ext_irq->interrupts[0],
+	                  ext_irq->active_high_low, ext_irq->edge_level);
+#else
+		req->irq = ext_irq->interrupts[0];
+#endif
+	}
+	return AE_OK;
+}
+
+static acpi_status acpi_serial_port(struct serial_struct *req,
+				    struct acpi_resource_io *io)
+{
+	req->port = io->min_base_address;
+	req->io_type = SERIAL_IO_PORT;
+	return AE_OK;
+}
+
+static acpi_status acpi_serial_irq(struct serial_struct *req,
+				   struct acpi_resource_irq *irq)
+{
+	if (irq->number_of_interrupts > 0) {
+#ifdef CONFIG_IA64
+		req->irq = acpi_register_irq(irq->interrupts[0],
+	                  irq->active_high_low, irq->edge_level);
+#else
+		req->irq = irq->interrupts[0];
+#endif
+	}
+	return AE_OK;
+}
+
+static acpi_status acpi_serial_resource(struct acpi_resource *res, void *data)
+{
+	struct serial_struct *serial_req = (struct serial_struct *) data;
+	struct acpi_resource_address64 addr;
+	acpi_status status;
+
+	status = acpi_resource_to_address64(res, &addr);
+	if (ACPI_SUCCESS(status))
+		return acpi_serial_address(serial_req, &addr);
+	else if (res->id == ACPI_RSTYPE_EXT_IRQ)
+		return acpi_serial_ext_irq(serial_req, &res->data.extended_irq);
+	else if (res->id == ACPI_RSTYPE_IO)
+		return acpi_serial_port(serial_req, &res->data.io);
+	else if (res->id == ACPI_RSTYPE_IRQ)
+		return acpi_serial_irq(serial_req, &res->data.irq);
+	return AE_OK;
+}
+
+static int acpi_serial_add(struct acpi_device *device)
+{
+	acpi_status status;
+	struct serial_struct serial_req;
+	int line;
+
+	memset(&serial_req, 0, sizeof(serial_req));
+
+	status = acpi_walk_resources(device->handle, METHOD_NAME__CRS,
+				     acpi_serial_resource, &serial_req);
+	if (ACPI_FAILURE(status))
+		return -ENODEV;
+
+	if (!serial_req.iomem_base && !serial_req.port) {
+		printk("%s: no iomem or port address in %s _CRS\n", __FUNCTION__,
+			device->pnp.bus_id);
+		return -ENODEV;
+	}
+
+	serial_req.baud_base = BASE_BAUD;
+	serial_req.flags = ASYNC_SKIP_TEST|ASYNC_BOOT_AUTOCONF|ASYNC_AUTO_IRQ;
+	serial_req.xmit_fifo_size = serial_req.custom_divisor = 0;
+	serial_req.close_delay = serial_req.hub6 = serial_req.closing_wait = 0;
+	serial_req.iomem_reg_shift = 0;
+
+	line = register_serial(&serial_req);
+	if (line < 0)
+		return -ENODEV;
+
+	return 0;
+}
+
+static int acpi_serial_remove(struct acpi_device *device, int type)
+{
+	return 0;
+}
+
+static struct acpi_driver acpi_serial_driver = {
+	.name =		"serial",
+	.class =	"",
+	.ids =		"PNP0501",
+	.ops =	{
+		.add =		acpi_serial_add,
+		.remove =	acpi_serial_remove,
+	},
+};
+
+static void __devinit probe_serial_acpi(void)
+{
+	acpi_bus_register_driver(&acpi_serial_driver);
+}
+#endif /* ENABLE_SERIAL_ACPI */
 
 static struct pci_device_id serial_pci_tbl[] __devinitdata = {
 	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960,
@@ -5550,6 +5752,9 @@
 		tty_register_devfs(&callout_driver, 0,
 				   callout_driver.minor_start + state->line);
 	}
+#ifdef ENABLE_SERIAL_ACPI
+	probe_serial_acpi();
+#endif
 #ifdef ENABLE_SERIAL_PCI
 	probe_serial_pci();
 #endif
@@ -5727,6 +5932,8 @@
 
 	/* printk("Unloading %s: version %s\n", serial_name, serial_version); */
 	del_timer_sync(&serial_timer);
+	if (hp_diva_count > 0)
+		del_timer_sync(&hp_diva_timer);
 	save_flags(flags); cli();
         remove_bh(SERIAL_BH);
 	if ((e1 = tty_unregister_driver(&serial_driver)))
diff -Nru a/fs/inode.c b/fs/inode.c
--- a/fs/inode.c	Thu Nov 20 16:16:44 2003
+++ b/fs/inode.c	Thu Nov 20 16:16:44 2003
@@ -56,7 +56,7 @@
  */
 
 static LIST_HEAD(inode_in_use);
-static LIST_HEAD(inode_unused);
+LIST_HEAD(inode_unused);
 static struct list_head *inode_hashtable;
 static LIST_HEAD(anon_hash_chain); /* for inodes with NULL i_sb */